<!DOCTYPE html>
<html lang="" xml:lang="">
<head>

  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <title>Chapter 6 External Library | JavaScript for R</title>
  <meta name="description" content="Invite JavaScript into your Data Science workflow." />
  <meta name="generator" content="bookdown 0.19 and GitBook 2.6.7" />

  <meta property="og:title" content="Chapter 6 External Library | JavaScript for R" />
  <meta property="og:type" content="book" />
  
  
  <meta property="og:description" content="Invite JavaScript into your Data Science workflow." />
  <meta name="github-repo" content="yihui/bookdown-crc" />

  <meta name="twitter:card" content="summary" />
  <meta name="twitter:title" content="Chapter 6 External Library | JavaScript for R" />
  
  <meta name="twitter:description" content="Invite JavaScript into your Data Science workflow." />
  

<meta name="author" content="John Coene" />


<meta name="date" content="2020-06-05" />

  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <meta name="apple-mobile-web-app-capable" content="yes" />
  <meta name="apple-mobile-web-app-status-bar-style" content="black" />
  
  
<link rel="prev" href="basic-widget.html"/>
<link rel="next" href="advanced.html"/>
<script src="libs/header-attrs/header-attrs.js"></script>
<script src="libs/jquery/jquery.min.js"></script>
<link href="libs/gitbook/css/style.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-table.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-bookdown.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-highlight.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-search.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-fontsettings.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-clipboard.css" rel="stylesheet" />









<script src="libs/htmlwidgets/htmlwidgets.js"></script>
<script src="libs/plotly-binding/plotly.js"></script>
<script src="libs/typedarray/typedarray.min.js"></script>
<link href="libs/crosstalk/css/crosstalk.css" rel="stylesheet" />
<script src="libs/crosstalk/js/crosstalk.min.js"></script>
<link href="libs/plotly-htmlwidgets-css/plotly-htmlwidgets.css" rel="stylesheet" />
<script src="libs/plotly-main/plotly-latest.min.js"></script>
<script src="libs/core-js/shim.min.js"></script>
<script src="libs/react/react.min.js"></script>
<script src="libs/react/react-dom.min.js"></script>
<script src="libs/reactwidget/react-tools.js"></script>
<script src="libs/reactable-binding/reactable.js"></script>
<script src="libs/r2d3-render/r2d3-render.js"></script>
<script src="libs/webcomponents/webcomponents.js"></script>
<script src="libs/r2d3-binding/r2d3.js"></script>
<script src="libs/d3v5/d3.min.js"></script>


<style type="text/css">
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
  { counter-reset: source-line 0; }
pre.numberSource code > span
  { position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::before
  { content: counter(source-line);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
    color: #aaaaaa;
  }
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
div.sourceCode
  {   }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
</style>

<link rel="stylesheet" href="css/style.css" type="text/css" />
</head>

<body>



  <div class="book without-animation with-summary font-size-2 font-family-1" data-basepath=".">

    <div class="book-summary">
      <nav role="navigation">

<ul class="summary">
<li><a href="./">R and JavaScript</a></li>

<li class="divider"></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html"><i class="fa fa-check"></i>Preface</a>
<ul>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#disclaimer"><i class="fa fa-check"></i>Disclaimer</a></li>
</ul></li>
<li class="part"><span><b>I Basics &amp; Roadmap</b></span></li>
<li class="chapter" data-level="1" data-path="introduction.html"><a href="introduction.html"><i class="fa fa-check"></i><b>1</b> Introduction</a>
<ul>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#rationale"><i class="fa fa-check"></i>Rationale</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#prerequisites"><i class="fa fa-check"></i>Prerequisites</a>
<ul>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#package-development"><i class="fa fa-check"></i>Package Development</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#json"><i class="fa fa-check"></i>JSON</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#javascript"><i class="fa fa-check"></i>JavaScript</a></li>
</ul></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#methods"><i class="fa fa-check"></i>Methods</a>
<ul>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#v8"><i class="fa fa-check"></i>V8</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#htmlwidgets"><i class="fa fa-check"></i>htmlwidgets</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#shiny"><i class="fa fa-check"></i>Shiny</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#reactr"><i class="fa fa-check"></i>reactR</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#bubble"><i class="fa fa-check"></i>bubble</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#r2d3"><i class="fa fa-check"></i>r2d3</a></li>
</ul></li>
</ul></li>
<li class="part"><span><b>II JavaScript for Computations</b></span></li>
<li class="chapter" data-level="2" data-path="the-v8-engine.html"><a href="the-v8-engine.html"><i class="fa fa-check"></i><b>2</b> The V8 Engine</a>
<ul>
<li class="chapter" data-level="" data-path="the-v8-engine.html"><a href="the-v8-engine.html#installation"><i class="fa fa-check"></i>Installation</a></li>
<li class="chapter" data-level="" data-path="the-v8-engine.html"><a href="the-v8-engine.html#basics"><i class="fa fa-check"></i>Basics</a></li>
<li class="chapter" data-level="" data-path="the-v8-engine.html"><a href="the-v8-engine.html#external-libraries"><i class="fa fa-check"></i>External Libraries</a></li>
<li class="chapter" data-level="" data-path="the-v8-engine.html"><a href="the-v8-engine.html#with-npm"><i class="fa fa-check"></i>With Npm</a></li>
<li class="chapter" data-level="" data-path="the-v8-engine.html"><a href="the-v8-engine.html#use-in-packages"><i class="fa fa-check"></i>Use in Packages</a></li>
</ul></li>
<li class="chapter" data-level="3" data-path="node.html"><a href="node.html"><i class="fa fa-check"></i><b>3</b> Node.js with Bubble</a>
<ul>
<li class="chapter" data-level="" data-path="node.html"><a href="node.html#basics-1"><i class="fa fa-check"></i>Basics</a></li>
<li class="chapter" data-level="" data-path="node.html"><a href="node.html#r-markdown-engine"><i class="fa fa-check"></i>R Markdown Engine</a></li>
<li class="chapter" data-level="" data-path="node.html"><a href="node.html#npm"><i class="fa fa-check"></i>Npm</a></li>
<li class="chapter" data-level="" data-path="node.html"><a href="node.html#use-in-packages-1"><i class="fa fa-check"></i>Use in Packages</a></li>
</ul></li>
<li class="part"><span><b>III Web Development with Shiny</b></span></li>
<li class="chapter" data-level="4" data-path="a-two-way-street.html"><a href="a-two-way-street.html"><i class="fa fa-check"></i><b>4</b> A Two-way Street</a>
<ul>
<li class="chapter" data-level="" data-path="a-two-way-street.html"><a href="a-two-way-street.html#static-files"><i class="fa fa-check"></i>Static Files</a></li>
<li class="chapter" data-level="" data-path="a-two-way-street.html"><a href="a-two-way-street.html#integration"><i class="fa fa-check"></i>Integration</a></li>
<li class="chapter" data-level="" data-path="a-two-way-street.html"><a href="a-two-way-street.html#from-r-to-javascript"><i class="fa fa-check"></i>From R to JavaScript</a></li>
<li class="chapter" data-level="" data-path="a-two-way-street.html"><a href="a-two-way-street.html#from-javascript-to-r"><i class="fa fa-check"></i>From JavaScript to R</a></li>
<li class="chapter" data-level="" data-path="a-two-way-street.html"><a href="a-two-way-street.html#external-library"><i class="fa fa-check"></i>External Library</a></li>
<li class="chapter" data-level="" data-path="a-two-way-street.html"><a href="a-two-way-street.html#serialisation"><i class="fa fa-check"></i>Serialisation</a></li>
<li class="chapter" data-level="" data-path="a-two-way-street.html"><a href="a-two-way-street.html#events-callbacks"><i class="fa fa-check"></i>Events &amp; Callbacks</a></li>
<li class="chapter" data-level="" data-path="a-two-way-street.html"><a href="a-two-way-street.html#as-a-package"><i class="fa fa-check"></i>As a Package</a>
<ul>
<li class="chapter" data-level="" data-path="a-two-way-street.html"><a href="a-two-way-street.html#dependencies"><i class="fa fa-check"></i>Dependencies</a></li>
<li class="chapter" data-level="" data-path="a-two-way-street.html"><a href="a-two-way-street.html#r-code"><i class="fa fa-check"></i>R Code</a></li>
<li class="chapter" data-level="" data-path="a-two-way-street.html"><a href="a-two-way-street.html#javascript-code"><i class="fa fa-check"></i>JavaScript Code</a></li>
<li class="chapter" data-level="" data-path="a-two-way-street.html"><a href="a-two-way-street.html#shortcoming"><i class="fa fa-check"></i>Shortcoming</a></li>
<li class="chapter" data-level="" data-path="a-two-way-street.html"><a href="a-two-way-street.html#input"><i class="fa fa-check"></i>Input</a></li>
<li class="chapter" data-level="" data-path="a-two-way-street.html"><a href="a-two-way-street.html#wrapping-up"><i class="fa fa-check"></i>Wrapping up</a></li>
</ul></li>
<li class="chapter" data-level="" data-path="a-two-way-street.html"><a href="a-two-way-street.html#exercises"><i class="fa fa-check"></i>Exercises</a></li>
</ul></li>
<li class="part"><span><b>IV HTML Widgets Visualisation</b></span></li>
<li class="chapter" data-level="5" data-path="basic-widget.html"><a href="basic-widget.html"><i class="fa fa-check"></i><b>5</b> Basic Widget</a>
<ul>
<li class="chapter" data-level="" data-path="basic-widget.html"><a href="basic-widget.html#candidate-libraries"><i class="fa fa-check"></i>Candidate Libraries</a>
<ul>
<li class="chapter" data-level="" data-path="basic-widget.html"><a href="basic-widget.html#plotly"><i class="fa fa-check"></i>Plotly</a></li>
<li class="chapter" data-level="" data-path="basic-widget.html"><a href="basic-widget.html#highchart.js"><i class="fa fa-check"></i>Highchart.js</a></li>
<li class="chapter" data-level="" data-path="basic-widget.html"><a href="basic-widget.html#chart.js"><i class="fa fa-check"></i>Chart.js</a></li>
</ul></li>
<li class="chapter" data-level="" data-path="basic-widget.html"><a href="basic-widget.html#how-it-works"><i class="fa fa-check"></i>How it works</a></li>
<li class="chapter" data-level="" data-path="basic-widget.html"><a href="basic-widget.html#the-scaffold"><i class="fa fa-check"></i>The Scaffold</a></li>
<li class="chapter" data-level="" data-path="basic-widget.html"><a href="basic-widget.html#the-output"><i class="fa fa-check"></i>The Output</a></li>
</ul></li>
<li class="chapter" data-level="6" data-path="external-library-1.html"><a href="external-library-1.html"><i class="fa fa-check"></i><b>6</b> External Library</a>
<ul>
<li class="chapter" data-level="" data-path="external-library-1.html"><a href="external-library-1.html#dependency"><i class="fa fa-check"></i>Dependency</a></li>
<li class="chapter" data-level="" data-path="external-library-1.html"><a href="external-library-1.html#javascript-1"><i class="fa fa-check"></i>JavaScript</a></li>
<li class="chapter" data-level="" data-path="external-library-1.html"><a href="external-library-1.html#html-element"><i class="fa fa-check"></i>HTML Element</a></li>
<li class="chapter" data-level="" data-path="external-library-1.html"><a href="external-library-1.html#exercises-1"><i class="fa fa-check"></i>Exercises</a></li>
</ul></li>
<li class="chapter" data-level="7" data-path="advanced.html"><a href="advanced.html"><i class="fa fa-check"></i><b>7</b> Advanced</a>
<ul>
<li class="chapter" data-level="" data-path="advanced.html"><a href="advanced.html#dependencies-1"><i class="fa fa-check"></i>Dependencies</a></li>
<li class="chapter" data-level="" data-path="advanced.html"><a href="advanced.html#javascript-2"><i class="fa fa-check"></i>JavaScript</a></li>
<li class="chapter" data-level="" data-path="advanced.html"><a href="advanced.html#working-with-data"><i class="fa fa-check"></i>Working with Data</a></li>
<li class="chapter" data-level="" data-path="advanced.html"><a href="advanced.html#transforming-data"><i class="fa fa-check"></i>Transforming Data</a>
<ul>
<li class="chapter" data-level="" data-path="advanced.html"><a href="advanced.html#in-javascript"><i class="fa fa-check"></i>In JavaScript</a></li>
<li class="chapter" data-level="" data-path="advanced.html"><a href="advanced.html#in-r"><i class="fa fa-check"></i>In R</a></li>
<li class="chapter" data-level="" data-path="advanced.html"><a href="advanced.html#pros-cons"><i class="fa fa-check"></i>Pros &amp; Cons</a></li>
</ul></li>
<li class="chapter" data-level="" data-path="advanced.html"><a href="advanced.html#on-print"><i class="fa fa-check"></i>On Print</a></li>
<li class="chapter" data-level="" data-path="advanced.html"><a href="advanced.html#javascript-functions"><i class="fa fa-check"></i>JavaScript Functions</a></li>
</ul></li>
<li class="chapter" data-level="" data-path="references.html"><a href="references.html"><i class="fa fa-check"></i>References</a></li>
</ul>

      </nav>
    </div>

    <div class="book-body">
      <div class="body-inner">
        <div class="book-header" role="navigation">
          <h1>
            <i class="fa fa-circle-o-notch fa-spin"></i><a href="./">JavaScript for R</a>
          </h1>
        </div>

        <div class="page-wrapper" tabindex="-1" role="main">
          <div class="page-inner">

            <section class="normal" id="section-">
<div id="external-library-1" class="section level1" number="6">
<h1><span class="header-section-number">Chapter 6</span> External Library</h1>
<p>In this section we build a package called <code>typed</code>, which wraps the JavaScript library of the same name, <a href="https://github.com/mattboldt/typed.js/">typed.js</a> that mimics text being typed. This builds upon many things we explored in the playground package.</p>
<div class="sourceCode" id="cb185"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb185-1"><a href="external-library-1.html#cb185-1"></a>usethis<span class="op">::</span><span class="kw">create_package</span>(<span class="st">&quot;typed&quot;</span>)</span>
<span id="cb185-2"><a href="external-library-1.html#cb185-2"></a>htmlwidgets<span class="op">::</span><span class="kw">scaffoldWidget</span>(<span class="st">&quot;typed&quot;</span>)</span></code></pre></div>
<p>As done with candidate libraries, let’s take a look at documentation of <a href="https://github.com/mattboldt/typed.js/">typed.js</a> to see how typed.js works.</p>
<div class="sourceCode" id="cb186"><pre class="sourceCode html"><code class="sourceCode html"><span id="cb186-1"><a href="external-library-1.html#cb186-1"></a><span class="dt">&lt;!DOCTYPE </span>html<span class="dt">&gt;</span></span>
<span id="cb186-2"><a href="external-library-1.html#cb186-2"></a><span class="kw">&lt;html</span><span class="ot"> xmlns=</span><span class="st">&quot;http://www.w3.org/1999/xhtml&quot;</span><span class="ot"> lang=</span><span class="st">&quot;&quot;</span><span class="ot"> xml:lang=</span><span class="st">&quot;&quot;</span><span class="kw">&gt;</span></span>
<span id="cb186-3"><a href="external-library-1.html#cb186-3"></a></span>
<span id="cb186-4"><a href="external-library-1.html#cb186-4"></a><span class="kw">&lt;head&gt;</span></span>
<span id="cb186-5"><a href="external-library-1.html#cb186-5"></a>  <span class="co">&lt;!-- Import library --&gt;</span></span>
<span id="cb186-6"><a href="external-library-1.html#cb186-6"></a>  <span class="kw">&lt;script</span><span class="ot"> src=</span><span class="st">&quot;typed.js&quot;</span><span class="kw">&gt;&lt;/script&gt;</span></span>
<span id="cb186-7"><a href="external-library-1.html#cb186-7"></a><span class="kw">&lt;/head&gt;</span></span>
<span id="cb186-8"><a href="external-library-1.html#cb186-8"></a></span>
<span id="cb186-9"><a href="external-library-1.html#cb186-9"></a><span class="kw">&lt;body&gt;</span></span>
<span id="cb186-10"><a href="external-library-1.html#cb186-10"></a>  <span class="co">&lt;!-- div to hold visualisation --&gt;</span></span>
<span id="cb186-11"><a href="external-library-1.html#cb186-11"></a>  <span class="kw">&lt;div</span><span class="ot"> class=</span><span class="st">&quot;element&quot;</span><span class="kw">&gt;&lt;/div&gt;</span></span>
<span id="cb186-12"><a href="external-library-1.html#cb186-12"></a></span>
<span id="cb186-13"><a href="external-library-1.html#cb186-13"></a>  <span class="co">&lt;!-- Script to create visualsiation --&gt;</span></span>
<span id="cb186-14"><a href="external-library-1.html#cb186-14"></a>  <span class="kw">&lt;script&gt;</span></span>
<span id="cb186-15"><a href="external-library-1.html#cb186-15"></a>    <span class="kw">var</span> typed <span class="op">=</span> <span class="kw">new</span> <span class="at">Typed</span>(<span class="st">&#39;.element&#39;</span><span class="op">,</span> <span class="op">{</span></span>
<span id="cb186-16"><a href="external-library-1.html#cb186-16"></a>      <span class="dt">strings</span><span class="op">:</span> [<span class="st">&#39;First sentence.&#39;</span><span class="op">,</span> <span class="st">&#39;And a second sentence.&#39;</span>]</span>
<span id="cb186-17"><a href="external-library-1.html#cb186-17"></a>    <span class="op">}</span>)<span class="op">;</span></span>
<span id="cb186-18"><a href="external-library-1.html#cb186-18"></a>  <span class="kw">&lt;/script&gt;</span></span>
<span id="cb186-19"><a href="external-library-1.html#cb186-19"></a><span class="kw">&lt;/body&gt;</span></span>
<span id="cb186-20"><a href="external-library-1.html#cb186-20"></a></span>
<span id="cb186-21"><a href="external-library-1.html#cb186-21"></a><span class="kw">&lt;/html&gt;</span></span></code></pre></div>
<p>The code above is not very different from what was observed in other libraries: the library is imported, there is a <code>&lt;div&gt;</code> where the output will be generated, and a script which also takes a selector and a JSON of options.</p>
<div id="dependency" class="section level2 unnumbered" number="">
<h2>Dependency</h2>
<p>Once the package created and the widget scaffold laid down we need to add the JavaScript dependency without which nothing can move forward. The <a href="https://github.com/mattboldt/typed.js">documentation in the README of typed.js</a> states that it can be imported like so.</p>
<div class="sourceCode" id="cb187"><pre class="sourceCode html"><code class="sourceCode html"><span id="cb187-1"><a href="external-library-1.html#cb187-1"></a><span class="kw">&lt;script</span><span class="ot"> src=</span><span class="st">&quot;https://cdn.jsdelivr.net/npm/typed.js@2.0.11&quot;</span><span class="kw">&gt;&lt;/script&gt;</span></span></code></pre></div>
<p>First, we will download the dependency, which consists of a single JavaScript file, instead of using the CDN as this ultimately makes the package more robust (more easily reproducible outputs and no requirement for internet connection). Below we place the dependency in a “typed” directory within the “htmlwidgets” folder.</p>
<div class="sourceCode" id="cb188"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb188-1"><a href="external-library-1.html#cb188-1"></a><span class="kw">dir.create</span>(<span class="st">&quot;./inst/htmlwidgets/typed&quot;</span>)</span>
<span id="cb188-2"><a href="external-library-1.html#cb188-2"></a>cdn &lt;-<span class="st"> &quot;https://cdn.jsdelivr.net/npm/typed.js@2.0.11&quot;</span></span>
<span id="cb188-3"><a href="external-library-1.html#cb188-3"></a><span class="kw">download.file</span>(cdn, <span class="st">&quot;./inst/htmlwidgets/typed/typed.min.js&quot;</span>)</span></code></pre></div>
<p>This produces a directory that looks like this:</p>
<pre><code>.
├── DESCRIPTION
├── NAMESPACE
├── R
│   └── typed.R
└── inst
    └── htmlwidgets
        ├── typed
        │   └── typed.min.js
        ├── typed.js
        └── typed.yaml</code></pre>
<p>In htmlwidgets packages dependencies are specified in the <code>.yml</code> file located at <code>inst/htmlwidgets</code> which at first contains a commented template.</p>
<div class="sourceCode" id="cb190"><pre class="sourceCode yml"><code class="sourceCode yaml"><span id="cb190-1"><a href="external-library-1.html#cb190-1"></a><span class="co"># (uncomment to add a dependency)</span></span>
<span id="cb190-2"><a href="external-library-1.html#cb190-2"></a><span class="co"># dependencies:</span></span>
<span id="cb190-3"><a href="external-library-1.html#cb190-3"></a><span class="co">#  - name:</span></span>
<span id="cb190-4"><a href="external-library-1.html#cb190-4"></a><span class="co">#    version:</span></span>
<span id="cb190-5"><a href="external-library-1.html#cb190-5"></a><span class="co">#    src:</span></span>
<span id="cb190-6"><a href="external-library-1.html#cb190-6"></a><span class="co">#    script:</span></span>
<span id="cb190-7"><a href="external-library-1.html#cb190-7"></a><span class="co">#    stylesheet:</span></span></code></pre></div>
<p>Let’s uncomment those lines as instructed at the top of the file and fill it in.</p>
<div class="sourceCode" id="cb191"><pre class="sourceCode yml"><code class="sourceCode yaml"><span id="cb191-1"><a href="external-library-1.html#cb191-1"></a><span class="fu">dependencies</span><span class="kw">:</span></span>
<span id="cb191-2"><a href="external-library-1.html#cb191-2"></a><span class="at">  </span><span class="kw">-</span><span class="at"> </span><span class="fu">name</span><span class="kw">:</span><span class="at"> typed.js</span></span>
<span id="cb191-3"><a href="external-library-1.html#cb191-3"></a><span class="at">    </span><span class="fu">version</span><span class="kw">:</span><span class="at"> </span><span class="fl">2.0.11</span></span>
<span id="cb191-4"><a href="external-library-1.html#cb191-4"></a><span class="at">    </span><span class="fu">src</span><span class="kw">:</span><span class="at"> htmlwidgets/typed</span></span>
<span id="cb191-5"><a href="external-library-1.html#cb191-5"></a><span class="at">    </span><span class="fu">script</span><span class="kw">:</span><span class="at"> typed.min.js</span></span></code></pre></div>
<p>We remove the <code>stylesheet</code> entry as this package does not require any CSS files. The <code>src</code> specifies the path to the directory containing the scripts and stylesheets. This is akin to using the <code>system.file</code> function to return the full path to a file or directory within the package.</p>
<div class="sourceCode" id="cb192"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb192-1"><a href="external-library-1.html#cb192-1"></a>devtools<span class="op">::</span><span class="kw">load_all</span>()</span>
<span id="cb192-2"><a href="external-library-1.html#cb192-2"></a><span class="kw">system.file</span>(<span class="st">&quot;htmlwidgets/typed&quot;</span>, <span class="dt">package =</span> <span class="st">&quot;typed&quot;</span>)                                         </span>
<span id="cb192-3"><a href="external-library-1.html#cb192-3"></a><span class="co">#&gt; &quot;/home/me/packages/typed/inst/htmlwidgets/typed&quot;</span></span></code></pre></div>
<p>We should verify that this is correct by using the one R function the package features and check the source code of the output to verify that the typed.js is indeed imported. We thus run <code>typed("test")</code>, open the output in the browser (<img src="images/open-in-browser.png" />) and look at the source code of the page (right click and select “View page source”). At the top of the page one should see <code>typed.min.js</code> imported, click the link to ensure it correctly points to the dependency.</p>
<div class="sourceCode" id="cb193"><pre class="sourceCode html"><code class="sourceCode html"><span id="cb193-1"><a href="external-library-1.html#cb193-1"></a><span class="dt">&lt;!DOCTYPE </span>html<span class="dt">&gt;</span></span>
<span id="cb193-2"><a href="external-library-1.html#cb193-2"></a><span class="kw">&lt;html&gt;</span></span>
<span id="cb193-3"><a href="external-library-1.html#cb193-3"></a><span class="kw">&lt;head&gt;</span></span>
<span id="cb193-4"><a href="external-library-1.html#cb193-4"></a><span class="kw">&lt;meta</span><span class="ot"> charset=</span><span class="st">&quot;utf-8&quot;</span><span class="kw">/&gt;</span></span>
<span id="cb193-5"><a href="external-library-1.html#cb193-5"></a><span class="kw">&lt;style&gt;</span>body{<span class="kw">background-color</span>:<span class="cn">white</span><span class="op">;</span>}<span class="kw">&lt;/style&gt;</span></span>
<span id="cb193-6"><a href="external-library-1.html#cb193-6"></a><span class="kw">&lt;script</span><span class="ot"> src=</span><span class="st">&quot;lib/htmlwidgets-1.5.1/htmlwidgets.js&quot;</span><span class="kw">&gt;&lt;/script&gt;</span></span>
<span id="cb193-7"><a href="external-library-1.html#cb193-7"></a><span class="kw">&lt;script</span><span class="ot"> src=</span><span class="st">&quot;lib/typed.js-2.0.11/typed.min.js&quot;</span><span class="kw">&gt;&lt;/script&gt;</span></span>
<span id="cb193-8"><a href="external-library-1.html#cb193-8"></a><span class="kw">&lt;script</span><span class="ot"> src=</span><span class="st">&quot;lib/typed-binding-0.0.0.9000/typed.js&quot;</span><span class="kw">&gt;&lt;/script&gt;</span></span>
<span id="cb193-9"><a href="external-library-1.html#cb193-9"></a>...</span></code></pre></div>
</div>
<div id="javascript-1" class="section level2 unnumbered" number="">
<h2>JavaScript</h2>
<p>On its <a href="https://mattboldt.com/demos/typed-js/">official website</a>, typed.js gives the following example. The JavaScript function <code>Typed</code> takes two arguments, first the selector, the element to hold the output, second a JSON of options to specify what is being typed and a myriad of other things.</p>
<div class="sourceCode" id="cb194"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb194-1"><a href="external-library-1.html#cb194-1"></a><span class="kw">var</span> typed <span class="op">=</span> <span class="kw">new</span> <span class="at">Typed</span>(<span class="st">&#39;.element&#39;</span><span class="op">,</span> <span class="op">{</span></span>
<span id="cb194-2"><a href="external-library-1.html#cb194-2"></a>  <span class="dt">strings</span><span class="op">:</span> [<span class="st">&quot;First sentence.&quot;</span><span class="op">,</span> <span class="st">&quot;Second sentence.&quot;</span>]<span class="op">,</span></span>
<span id="cb194-3"><a href="external-library-1.html#cb194-3"></a>  <span class="dt">typeSpeed</span><span class="op">:</span> <span class="dv">30</span></span>
<span id="cb194-4"><a href="external-library-1.html#cb194-4"></a><span class="op">}</span>)<span class="op">;</span></span></code></pre></div>
<p>Let’s place it in the package by replacing the content of the <code>renderValue</code> in <code>typed.js</code> with the above.</p>
<div class="sourceCode" id="cb195"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb195-1"><a href="external-library-1.html#cb195-1"></a>...</span>
<span id="cb195-2"><a href="external-library-1.html#cb195-2"></a>renderValue<span class="op">:</span> <span class="kw">function</span>(x) <span class="op">{</span></span>
<span id="cb195-3"><a href="external-library-1.html#cb195-3"></a></span>
<span id="cb195-4"><a href="external-library-1.html#cb195-4"></a>  <span class="kw">var</span> typed <span class="op">=</span> <span class="kw">new</span> <span class="at">Typed</span>(<span class="st">&#39;.element&#39;</span><span class="op">,</span> <span class="op">{</span></span>
<span id="cb195-5"><a href="external-library-1.html#cb195-5"></a>    <span class="dt">strings</span><span class="op">:</span> [<span class="st">&quot;First sentence.&quot;</span><span class="op">,</span> <span class="st">&quot;Second sentence.&quot;</span>]<span class="op">,</span></span>
<span id="cb195-6"><a href="external-library-1.html#cb195-6"></a>    <span class="dt">typeSpeed</span><span class="op">:</span> <span class="dv">30</span></span>
<span id="cb195-7"><a href="external-library-1.html#cb195-7"></a>  <span class="op">}</span>)<span class="op">;</span></span>
<span id="cb195-8"><a href="external-library-1.html#cb195-8"></a></span>
<span id="cb195-9"><a href="external-library-1.html#cb195-9"></a><span class="op">}</span></span>
<span id="cb195-10"><a href="external-library-1.html#cb195-10"></a>...</span></code></pre></div>
<p>One could be tempted to run <code>devtools::load_all</code> but this will not work, namely because the function uses a selector that is will not return any object; it needs to be applied to the div created by the widget not <code>.element</code>. As hinted at in the playground, the selector of the element created is accessible from the <code>el</code> object. As a matter of fact, we did log in the browser console the id of the created div taken from <code>el.id</code>. Therefore concatenating the pound sign and the element id produces the select to said element. (<code>.class</code>, <code>#id</code>)</p>
<div class="sourceCode" id="cb196"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb196-1"><a href="external-library-1.html#cb196-1"></a><span class="co">// typed.js</span></span>
<span id="cb196-2"><a href="external-library-1.html#cb196-2"></a>...</span>
<span id="cb196-3"><a href="external-library-1.html#cb196-3"></a>renderValue<span class="op">:</span> <span class="kw">function</span>(x) <span class="op">{</span></span>
<span id="cb196-4"><a href="external-library-1.html#cb196-4"></a></span>
<span id="cb196-5"><a href="external-library-1.html#cb196-5"></a>  <span class="kw">var</span> typed <span class="op">=</span> <span class="kw">new</span> <span class="at">Typed</span>(<span class="st">&#39;#&#39;</span> <span class="op">+</span> <span class="va">el</span>.<span class="at">id</span><span class="op">,</span> <span class="op">{</span></span>
<span id="cb196-6"><a href="external-library-1.html#cb196-6"></a>    <span class="dt">strings</span><span class="op">:</span> [<span class="st">&quot;First sentence.&quot;</span><span class="op">,</span> <span class="st">&quot;Second sentence.&quot;</span>]<span class="op">,</span></span>
<span id="cb196-7"><a href="external-library-1.html#cb196-7"></a>    <span class="dt">typeSpeed</span><span class="op">:</span> <span class="dv">30</span></span>
<span id="cb196-8"><a href="external-library-1.html#cb196-8"></a>  <span class="op">}</span>)<span class="op">;</span></span>
<span id="cb196-9"><a href="external-library-1.html#cb196-9"></a></span>
<span id="cb196-10"><a href="external-library-1.html#cb196-10"></a><span class="op">}</span></span>
<span id="cb196-11"><a href="external-library-1.html#cb196-11"></a>...</span></code></pre></div>
<p>This should now work, run <code>devtools::load_all</code> followed by <code>typed("whatever")</code> and the JavaScript animated text will appear! It’s not of any use just yet as the options, included the text being typed is predefined: the package is currently not making any use the of the inputs passed from R. Below change the default strings to <code>x.message</code>.</p>
<div class="sourceCode" id="cb197"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb197-1"><a href="external-library-1.html#cb197-1"></a><span class="co">// typed.js</span></span>
<span id="cb197-2"><a href="external-library-1.html#cb197-2"></a>...</span>
<span id="cb197-3"><a href="external-library-1.html#cb197-3"></a>renderValue<span class="op">:</span> <span class="kw">function</span>(x) <span class="op">{</span></span>
<span id="cb197-4"><a href="external-library-1.html#cb197-4"></a></span>
<span id="cb197-5"><a href="external-library-1.html#cb197-5"></a>  <span class="kw">var</span> typed <span class="op">=</span> <span class="kw">new</span> <span class="at">Typed</span>(<span class="st">&#39;#&#39;</span> <span class="op">+</span> <span class="va">el</span>.<span class="at">id</span><span class="op">,</span> <span class="op">{</span></span>
<span id="cb197-6"><a href="external-library-1.html#cb197-6"></a>    <span class="dt">strings</span><span class="op">:</span> <span class="va">x</span>.<span class="at">message</span><span class="op">,</span></span>
<span id="cb197-7"><a href="external-library-1.html#cb197-7"></a>    <span class="dt">typeSpeed</span><span class="op">:</span> <span class="dv">30</span></span>
<span id="cb197-8"><a href="external-library-1.html#cb197-8"></a>  <span class="op">}</span>)<span class="op">;</span></span>
<span id="cb197-9"><a href="external-library-1.html#cb197-9"></a></span>
<span id="cb197-10"><a href="external-library-1.html#cb197-10"></a><span class="op">}</span></span>
<span id="cb197-11"><a href="external-library-1.html#cb197-11"></a>...</span></code></pre></div>
<p>This, however, will cause issues as the <code>strings</code> options expects and array (vector) and not a single string. This is something often forgotten when working with R, there is no scalar values, in R a scalar is vector of length 1.</p>
<div class="sourceCode" id="cb198"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb198-1"><a href="external-library-1.html#cb198-1"></a><span class="kw">typed</span>(<span class="st">&quot;does not work&quot;</span>) <span class="co"># length =  1</span></span>
<span id="cb198-2"><a href="external-library-1.html#cb198-2"></a><span class="kw">typed</span>(<span class="kw">c</span>(<span class="st">&quot;This&quot;</span>, <span class="st">&quot;will&quot;</span>, <span class="st">&quot;work&quot;</span>)) <span class="co"># length &gt; 1</span></span></code></pre></div>
<p>One solution is to force the input into a list.</p>
<div class="sourceCode" id="cb199"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb199-1"><a href="external-library-1.html#cb199-1"></a><span class="co"># typed.R</span></span>
<span id="cb199-2"><a href="external-library-1.html#cb199-2"></a>x =<span class="st"> </span><span class="kw">list</span>(</span>
<span id="cb199-3"><a href="external-library-1.html#cb199-3"></a>  <span class="dt">message =</span> <span class="kw">as.list</span>(message)</span>
<span id="cb199-4"><a href="external-library-1.html#cb199-4"></a>)</span></code></pre></div>
<p>At this juncture the package works but there is a salient issue with the way it handles options. Why build a list in R to reconstruct it in JavaScript manually. Since the options are serialised in R to JSON and that typed.js expects a JSON of options it is actually cleaner and more convenient to construct an R list that mirrors the JSON array so one can use is as-is in JavaScript.</p>
<p>In fact, renaming the <code>message</code> to <code>strings</code> effectively does this.</p>
<div class="sourceCode" id="cb200"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb200-1"><a href="external-library-1.html#cb200-1"></a><span class="co"># typed.R</span></span>
<span id="cb200-2"><a href="external-library-1.html#cb200-2"></a>x =<span class="st"> </span><span class="kw">list</span>(</span>
<span id="cb200-3"><a href="external-library-1.html#cb200-3"></a>  <span class="dt">strings =</span> <span class="kw">as.list</span>(message)</span>
<span id="cb200-4"><a href="external-library-1.html#cb200-4"></a>)</span></code></pre></div>
<p>This allows greatly simplifying the code JavaScript side, making it much easier to add other options down the line, maintain, debug, and read.</p>
<div class="sourceCode" id="cb201"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb201-1"><a href="external-library-1.html#cb201-1"></a><span class="co">// typed.js</span></span>
<span id="cb201-2"><a href="external-library-1.html#cb201-2"></a>...</span>
<span id="cb201-3"><a href="external-library-1.html#cb201-3"></a>renderValue<span class="op">:</span> <span class="kw">function</span>(x) <span class="op">{</span></span>
<span id="cb201-4"><a href="external-library-1.html#cb201-4"></a></span>
<span id="cb201-5"><a href="external-library-1.html#cb201-5"></a>  <span class="kw">var</span> typed <span class="op">=</span> <span class="kw">new</span> <span class="at">Typed</span>(<span class="st">&#39;#&#39;</span> <span class="op">+</span> <span class="va">el</span>.<span class="at">id</span><span class="op">,</span> x)<span class="op">;</span></span>
<span id="cb201-6"><a href="external-library-1.html#cb201-6"></a></span>
<span id="cb201-7"><a href="external-library-1.html#cb201-7"></a><span class="op">}</span></span>
<span id="cb201-8"><a href="external-library-1.html#cb201-8"></a>...</span></code></pre></div>
<p>One can now add more options from the R code without having to alter any of the JavaScript. Let us demonstrate with the <code>loop</code> option.</p>
<div class="sourceCode" id="cb202"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb202-1"><a href="external-library-1.html#cb202-1"></a>typed &lt;-<span class="st"> </span><span class="cf">function</span>(message, <span class="dt">loop =</span> <span class="ot">FALSE</span>, <span class="dt">width =</span> <span class="ot">NULL</span>, <span class="dt">height =</span> <span class="ot">NULL</span>, <span class="dt">elementId =</span> <span class="ot">NULL</span>) {</span>
<span id="cb202-2"><a href="external-library-1.html#cb202-2"></a></span>
<span id="cb202-3"><a href="external-library-1.html#cb202-3"></a>  <span class="co"># forward options using x</span></span>
<span id="cb202-4"><a href="external-library-1.html#cb202-4"></a>  x =<span class="st"> </span><span class="kw">list</span>(</span>
<span id="cb202-5"><a href="external-library-1.html#cb202-5"></a>    <span class="dt">loop =</span> loop,</span>
<span id="cb202-6"><a href="external-library-1.html#cb202-6"></a>    <span class="dt">strings =</span> <span class="kw">as.list</span>(message)</span>
<span id="cb202-7"><a href="external-library-1.html#cb202-7"></a>  )</span>
<span id="cb202-8"><a href="external-library-1.html#cb202-8"></a></span>
<span id="cb202-9"><a href="external-library-1.html#cb202-9"></a>  <span class="co"># create widget</span></span>
<span id="cb202-10"><a href="external-library-1.html#cb202-10"></a>  htmlwidgets<span class="op">::</span><span class="kw">createWidget</span>(</span>
<span id="cb202-11"><a href="external-library-1.html#cb202-11"></a>    <span class="dt">name =</span> <span class="st">&#39;typed&#39;</span>,</span>
<span id="cb202-12"><a href="external-library-1.html#cb202-12"></a>    x,</span>
<span id="cb202-13"><a href="external-library-1.html#cb202-13"></a>    <span class="dt">width =</span> width,</span>
<span id="cb202-14"><a href="external-library-1.html#cb202-14"></a>    <span class="dt">height =</span> height,</span>
<span id="cb202-15"><a href="external-library-1.html#cb202-15"></a>    <span class="dt">package =</span> <span class="st">&#39;typed&#39;</span>,</span>
<span id="cb202-16"><a href="external-library-1.html#cb202-16"></a>    <span class="dt">elementId =</span> elementId</span>
<span id="cb202-17"><a href="external-library-1.html#cb202-17"></a>  )</span>
<span id="cb202-18"><a href="external-library-1.html#cb202-18"></a>}</span></code></pre></div>
</div>
<div id="html-element" class="section level2 unnumbered" number="">
<h2>HTML Element</h2>
<p>As pointed out multiple times, the widget is generated in a <code>&lt;div&gt;</code>, which is works fine for most visualisation libraries. But we saw that chart.js requires placing it in a <code>&lt;canvas&gt;</code>, so one needs the ability to change that. It could be interesting to apply this to typed.js too as within a <code>&lt;div&gt;</code> it cannot be placed inline, using a <code>&lt;span&gt;</code>, however, this would work.</p>
<p>This can be changed by placing a function named <code>nameOfWidget_html</code> which looked up by htmlwidgets and used if found. This function takes the three-dot construct <code>...</code> and uses them in an htmltools tag. The three-dots are necessary because internally htmlwidgets needs be able to pass arguments, such as the all too critical <code>id</code>.</p>
<div class="sourceCode" id="cb203"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb203-1"><a href="external-library-1.html#cb203-1"></a>typed_html &lt;-<span class="st"> </span><span class="cf">function</span>(...){</span>
<span id="cb203-2"><a href="external-library-1.html#cb203-2"></a>  htmltools<span class="op">::</span>tags<span class="op">$</span><span class="kw">span</span>(...)</span>
<span id="cb203-3"><a href="external-library-1.html#cb203-3"></a>}</span></code></pre></div>
</div>
<div id="exercises-1" class="section level2 unnumbered" number="">
<h2>Exercises</h2>
<p>The full list of which is available in the <a href="https://github.com/mattboldt/typed.js/#customization">documentation of typed.js</a>. There are multiple ways to complete this package with regard to the options that are made available R-side and the API one wants to provide users of the package.</p>
<ol style="list-style-type: decimal">
<li>Keep adding arguments as done with <code>loop</code></li>
<li>Use the three-dot construct (<code>...</code>) instead of adding arguments individually.</li>
<li>Provide other functions for additional options.</li>
</ol>
<p>It might be unclear how to implement the last point, this is something we’ll explore in the following section.</p>

</div>
</div>
            </section>

          </div>
        </div>
      </div>
<a href="basic-widget.html" class="navigation navigation-prev " aria-label="Previous page"><i class="fa fa-angle-left"></i></a>
<a href="advanced.html" class="navigation navigation-next " aria-label="Next page"><i class="fa fa-angle-right"></i></a>
    </div>
  </div>
<script src="libs/gitbook/js/app.min.js"></script>
<script src="libs/gitbook/js/lunr.js"></script>
<script src="libs/gitbook/js/clipboard.min.js"></script>
<script src="libs/gitbook/js/plugin-search.js"></script>
<script src="libs/gitbook/js/plugin-sharing.js"></script>
<script src="libs/gitbook/js/plugin-fontsettings.js"></script>
<script src="libs/gitbook/js/plugin-bookdown.js"></script>
<script src="libs/gitbook/js/jquery.highlight.js"></script>
<script src="libs/gitbook/js/plugin-clipboard.js"></script>
<script>
gitbook.require(["gitbook"], function(gitbook) {
gitbook.start({
"sharing": {
"github": true,
"facebook": false,
"twitter": false,
"linkedin": false,
"weibo": false,
"instapaper": false,
"vk": false,
"all": {}
},
"fontsettings": {
"theme": "white",
"family": "sans",
"size": 2
},
"edit": {
"link": "https://github.com/JohnCoene/r-and-javascript/edit/master/06-htmlwidgets-basic.Rmd",
"text": "Edit"
},
"history": {
"link": null,
"text": null
},
"view": {
"link": null,
"text": null
},
"download": {},
"toc": {
"collapse": "section"
}
});
});
</script>

</body>

</html>
